//
//  ViewController.m
//  DataBaseTest
//
//  Created by 赵小燕 on 16/12/11.
//  Copyright © 2016年 xiaoyanzhao. All rights reserved.
//

#import "ViewController.h"
#import "FMDB.h"
#import "FMDatabaseHelper.h"
#import "sqlite3.h"

static FMDatabase *dataBase;
static char dbPath[200];
static dispatch_queue_t queueR;
static dispatch_queue_t queueW;

static FMDatabaseHelper *queueFM;

static int lastReadCount = 0;
static int readCount = 0;
static int lastWriteCount = 0;
static int writeCount = 0;


@interface ViewController () {
//    FMDatabaseHelper *_queueFM;


}

//@property (nonatomic, strong) FMDatabaseHelper *queueFM;
//@property (nonatomic, strong) FMDatabaseQueue *queueT;



@end

@implementation ViewController

- (void)count {
    int lastRead = lastReadCount;
    int lastWrite = lastWriteCount;
    lastReadCount = readCount;
    lastWriteCount = writeCount;
    NSLog(@"%d, %d", lastReadCount - lastRead, lastWriteCount - lastWrite);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *directory = [path objectAtIndex:0];
    strcpy(dbPath, [[directory stringByAppendingPathComponent:@"dataFMDB.sqlite"] UTF8String]);
    NSLog(@"111111 %@", directory);
    
     dataBase = [FMDatabase databaseWithPath:[NSString stringWithUTF8String:dbPath]];
//    queueFM = [FMDatabaseQueue databaseQueueWithPath:[NSString stringWithUTF8String:dbPath]];
//    self.queueT = [FMDatabaseQueue databaseQueueWithPath:[NSString stringWithUTF8String:dbPath]];

    
//    char *errorMsg;
//    NSString *str = @"CREATE TABLE IF NOT EXISTS TEST (ID INTEGER PRIMARY KEY, VALUE INTEGER);";
//    if (sqlite3_exec(dataBase, [str UTF8String], nil, nil, &errorMsg) != SQLITE_OK) {
//        NSLog(@"Failed to create Table : %s", errorMsg);
//    }
    
    queueFM = [FMDatabaseHelper sharedInstance];
    
    if (![dataBase open]) {
        NSLog(@"FMDB open failed");
    } else {
    
    [dataBase executeUpdate:@"CREATE TABLE IF NOT EXISTS FM_INFO (ID INTEGER PRIMARY KEY, VALUE INTEGER);"];
    }
    
    if (dataBase) {
        [dataBase executeUpdate:@"DELETE FROM FM_INFO"];
    }
    
    queueR = dispatch_queue_create("queue.db", NULL);
    queueW = dispatch_queue_create("queue.db", NULL);
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(count) userInfo:nil repeats:YES];
    
    insertData();
    readData();
    writeData();
    
//    [dataBase close];

}

static void insertData() {
//    char *errorMsg;
//
//    if (sqlite3_exec(dataBase, "BEGIN TRANSACTION", NULL, NULL, &errorMsg) != SQLITE_OK) {
//        NSLog(@"failed to begin transaction : %s", errorMsg);
//    }
    
//    static const NSString *sql = @"INSERT INTO TEST VALUES (NULL, ?);";
//    sqlite3_stmt *stmt;
//    if (sqlite3_prepare_v2(dataBase, [sql UTF8String], -1, &stmt, NULL) == SQLITE_OK) {
//        for (int i = 0; i < 10; ++i) {
//            sqlite3_bind_int(stmt, 1, arc4random());
//            if (sqlite3_step(stmt) != SQLITE_DONE) {
//                --i;
//                NSLog(@"Error inserting table : %s", sqlite3_errmsg(dataBase));
//            }
//            sqlite3_reset(stmt);
//        }
//        sqlite3_finalize(stmt);
//    }
//    
//    if (sqlite3_exec(dataBase, "COMMIT TRANSACTION", NULL, NULL, &errorMsg) != SQLITE_OK) {
//        NSLog(@"failed to commit transaction: %s", errorMsg);
//    }
//    
//    static const char *query = "SELECT COUNT(*) FROM TEST;";
//    if (sqlite3_prepare_v2(dataBase, query, -1, &stmt, NULL) == SQLITE_OK) {
//        if (sqlite3_step(stmt) == SQLITE_ROW) {
//            NSLog(@"Table size: %d", sqlite3_column_int(stmt, 0));
//        } else {
//            NSLog(@"failed to read Table : %s", sqlite3_errmsg(dataBase));
//        }
//        sqlite3_finalize(stmt);
//    }
    [queueFM.queueDB inTransaction:^(FMDatabase *db, BOOL *rollback) {
        NSString *sql = @"INSERT INTO FM_INFO VALUES (NULL, ?);";
        BOOL result = 0;
        for (int i = 0; i < 10; ++i) {
            result = [db executeUpdate:sql, [NSNumber numberWithInt:arc4random()]];
        }
        
        if (!result) {
            *rollback = YES;
            return;
        }
    }];
    
//    [self.queueT inDatabase:^(FMDatabase *db) {
//        NSString *sql = @"INSERT INTO FM_INFO VALUES (NULL, ?);";
//        for (int i = 0; i < 10; ++i) {
//            [dataBase executeUpdate:sql, [NSNumber numberWithInt:arc4random()]];
//        }
//    }];

    
    static NSString *query = @"SELECT COUNT(*) FROM FM_INFO;";
    FMResultSet *s = [dataBase executeQuery:query];
    if ([s next]) {
        int totalCount = [s intForColumnIndex:0];
        NSLog(@"Table size : %d", totalCount);
    }
    [s close];
}

static void readData() {
//    static const char *query = "SELECT VALUE FROM TEST WHERE VALUE < ? ORDER BY VALUE DESC LIMIT 1;";
//    
//    static void (^ readBlock)() = ^(){
//        sqlite3_stmt *stmt;
//        if (sqlite3_prepare_v2(dataBase, query, -1, &stmt, NULL) == SQLITE_OK) {
//            sqlite3_bind_int(stmt, 1, arc4random());
//            int returnCode = sqlite3_step(stmt);
//            if (returnCode == SQLITE_ROW || returnCode == SQLITE_DONE) {
//                ++readCount;
//            }
//            sqlite3_finalize(stmt);
//        } else {
//            NSLog(@"failed to prepare statement : %s", sqlite3_errmsg(dataBase));
//        }
//        dispatch_async(queue, readBlock);
//    };
//    dispatch_async(queue, readBlock);
    
    static NSString *query = @"SELECT VALUE FROM FM_INFO WHERE VALUE < ? ORDER BY VALUE DESC LIMIT 1;";
    
    static void (^ readBlock)() = ^() {
        [queueFM.queueDB inDatabase:^(FMDatabase *db) {
            FMResultSet *set = [dataBase executeQuery:query, [NSNumber numberWithInt:arc4random()]];
            if ([set next]) {
                ++readCount;
            }
            [set close];
        }];
        dispatch_async(queueR, readBlock);
    };
    dispatch_async(queueR, readBlock);
}

static void writeData() {
//    static const char *update = "UPDATE test SET value = ? WHERE id = ?;";
//    
//    static void (^ writeBlock)() = ^{
//        sqlite3_stmt *stmt;
//        if (sqlite3_prepare_v2(dataBase, update, -1, &stmt, NULL) == SQLITE_OK) {
//            sqlite3_bind_int(stmt, 1, arc4random());
//            sqlite3_bind_int(stmt, 2, arc4random() % 10 + 1);
//            if (sqlite3_step(stmt) == SQLITE_DONE) {
//                ++writeCount;
//            }
//            sqlite3_finalize(stmt);
//        } else {
//            NSLog(@"failed to prepare statement : %s", sqlite3_errmsg(dataBase));
//        }
//        dispatch_async(queue, writeBlock);
//    };
//    dispatch_async(queue, writeBlock);
    
    static NSString *update = @"UPDATE FM_INFO SET VALUE = ? WHERE ID = ?;";
    
    static void (^ writeBlock)() = ^() {
    [queueFM.queueDB inDatabase:^(FMDatabase *db){
        [dataBase executeUpdate:update, [NSNumber numberWithInt:arc4random()], [NSNumber numberWithInt:(arc4random() % 10 + 1)]];
        ++writeCount;
    }];
        dispatch_async(queueW, writeBlock);
    };
    dispatch_async(queueW, writeBlock);
}

//static sqlite3 *openDb() {
//    if (sqlite3_open(dbPath, &dataBase) != SQLITE_OK) {
//        sqlite3_close(dataBase);
//        NSLog(@"failed to open database");
//    }
//    return dataBase;
//}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end
